package com.jame.basics.thread.thread_pond;

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 * @author : Jame
 * @date : 2021-01-15 13:41
 **/
public class ThreadPoolExecutorDemo {
    /**
     * 参数
     *    ThreadPoolExecutor(
     *    int corePoolSize,  //核心线程数量
     *    int maximumPoolSize, //最大线程数量
     *    long keepAliveTime,  //超过核心线程数量闲置线程存活时间
     *    TimeUnit unit, //超时单位
     *    BlockingQueue<Runnable> workQueue,  //阻塞队列
     *    ThreadFactory threadFactory,      //创建线程的工厂
     *    RejectedExecutionHandler handler  //拒绝策略
     *    )
     */
    public static void main(String[] args) throws InterruptedException {
        /**
         * 核心线程数量是固定的,即使没有执行任也会存活
         * 当需要执行的线程数量大于核心线程数量加上队列中线程数量时会创建其他线程来执行任务,
         * 核心线程数量加上其他线程数量总和不会大于最大线程数量
         * 当需要执行的线程数量小于队列线程数量加上核心线程数量时会销毁其他线程数量
         * 当核心线程和其他线程数量已经为最大线程数量,而队列中已经存满线程,会根据拒绝策略进行对应操作
         *
         */
        /**
         * 四种拒绝策略,当核心线程加上其他线程已经是最大线程数量,队列中已经满了
         * ThreadPoolExecutor.AbortPolicy() 抛出异常
         * ThreadPoolExecutor.CallerRunsPolicy() 哪来的回哪去,例如main线程调用,但是已经满了,那么让main线程执行任务
         * ThreadPoolExecutor.DiscardPolicy() 丢掉任务
         * ThreadPoolExecutor.DiscardOldestPolicy() 丢掉队列中最早进入的任务,然后将当前任务添加到队列
         * 下面的结果也可以说明,假设线程是顺序执行的,我也测试过10几次,一直没有3,
         * 一直输出没有3,原因最开始进入2个核心线程执行,然后队列中就是3 4 5 6 7
         * 然后8 9 10 进来激活了其他线程,11这时候进来队列最头是3,把3丢掉然后把11添加进队列
         */

        ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(
                2,
                Runtime.getRuntime().availableProcessors(),
                3,
                TimeUnit.SECONDS,
                new ArrayBlockingQueue<>(5),
                Executors.defaultThreadFactory(),
                new ThreadPoolExecutor.DiscardOldestPolicy());


        for (int i = 1; i <= 11; i++) {

            final int temp=i;

            threadPoolExecutor.execute(()->{
                System.out.println(Thread.currentThread().getName()+"=="+temp);
            });
        }


    }
}
